﻿var Eci = Eci || {}
Eci.Control = Eci.Control || {}

/**
 * 上传控件
 *
 */
Eci.Control.Progress = function (connOpt, options) {
  var obj = {
    /**
     * 上传控件窗体id
     */
    id: 'eci-upload-dialog',

    /**
     * 上传文件列表
     */
    uploadFiles: [],

    /**
     * 当前文件索引
     */
    currIndex: 0,

    /**
     * 最后一批文件的索引
     */
    lastIndex: 0,

    /**
     * 上传控件容器
     */
    uploadBoxId: 'upload',

    /**
     * WebSocket对象
     */
    channel: null,

    /**
     * 是否实名保存文件
     */
    IsRealName: null,

    /**
     * 是否启用单进度条
     */
    IsSingleProgress: false,

    /**
     * 单进度条id
     */
    progressContainerId: null,

    /**
     * 把上传控件的HTML添加到指定元素里
     */
    init: function (connOpt, options) {
      //  上传文件控件参数
      if (options.complete) {
        this.complete = options.complete
      }

      if (options.extract) {
        this.extract = options.extract
      }

      if (options.close) {
        this.close = options.close
      }

      if (options.error) {
        this.error = options.error
      }

      if (options.fileValid) {
        this.fileValid = options.fileValid
      }

      this.currIndex = 0
      this.lastIndex = 0
      this.IsRealName = connOpt.IsRealName
      if (connOpt.IsSingleProgress) this.IsSingleProgress = connOpt.IsSingleProgress
    },

    /**
     * 外部调用的关闭窗体事件
     */
    close: null,

    /**
     * 给指定id的元素添加上传控件的HTML
     */
    appendHTML: function () {
      var i = 6

      while (i--) {
        //  给上传控件容器随机生成一个id
        this.uploadBoxId += Math.floor(Math.random() * 16.0).toString(16)
      }

      var maskDiv = "<div id='mask-" + this.id + "' class='eci-progressbar-bg' style='display:none;'></div>"
      jQuery('body').append(maskDiv)

      //  把上传控件添加到body标签里
      var uploadDiv =
        '<div class="eci-progressbar" style="display:none;"><div id="' +
        this.id +
        '" class="eci-progressbar-container-box"></div></div>'
      jQuery('body').append(uploadDiv)

      var header = document.getElementById('mask-' + this.id)
      document.addEventListener('scroll', function (e) {
        window.scrollY >= header.offsetTop ? header.classList.add('sticky') : header.classList.remove('sticky')
      })
    },

    /**
     * 验证文件名
     */
    fileValid: null,

    /**
     * 连接次数
     */
    reConnectTimes: 0,

    /**
     * 连接次数
     */
    isUploading: false,

    /**
     * 集线器名称
     */
    channelName: 'uploadHub',

    /**
     * 重连服务器
     */
    reConnectServer: function () {
      this.channel.reConnectServer()
    },

    /**
     * 文件续传
     */
    continueUpload: function (file, channel) {
      setTimeout(function () {
        file.ContinueUpload(channel, 'Handler.UploadFile')
      }, 200)
    },

    /**
     * 文件解压
     */
    extractFileToGuid: function (file, channel) {
      setTimeout(function () {
        file.extractFileToGuid(channel, 'Handler.UploadFile')
      }, 200)
    },

    /**
     * 连接服务器
     */
    connectServer: function (option, upload) {
      var that = this

      this.channel = new Eci.Communication.Channel(this.channelName)
      //  WebSocket连接
      this.channel.connected = function (evt) {
        $('#mask-' + that.id).show()
        $('#eci-upload-dialog').parent().show()

        that.reConnectTimes = 0

        if (option.connected) {
          option.connected(evt)
        }

        upload()
      }

      this.errorFile = function (evt) {
        that.isUploading = false

        for (var i = 0, fileLen = that.uploadFiles.length; i < fileLen; i++) {
          var file = that.uploadFiles[i]
          if (!file.IsComplete) {
            that.isUploading = true
            file.IsStop = true
            //var eciProgress = "eci_p_progress_" + file.ID;
            var eciProgressNum = 'eci_p_num_' + file.ID
            //document.getElementById(eciProgress).style.backgroundColor = "#F44336";
            $('#' + eciProgressNum).html('Reconnecting')

            var closedSector = $('#eci_p_close_' + file.ID)
            closedSector.removeClass('icon-icon_No')
            closedSector.addClass('icon-sup-0039-go-back')
          }
        }
      }

      //  接收异常信息
      this.channel.error = function (evt) {
        if (evt.message) {
          console.log(evt.message)
          that.errorFile(evt)
          that.error(Eci.Resource.NotConnected)
        } else {
          console.error(evt)
          that.error(evt.Error)
        }
      }

      //  WebSocket关闭
      this.channel.disposed = function (evt) {
        if (option.disposed) {
          option.disposed(evt)
        }

        if (that.isUploading) {
          for (var i = 0, fileLen = that.uploadFiles.length; i < fileLen; i++) {
            var file = that.uploadFiles[i]
            if (!file.IsComplete) {
              $('#' + 'eci_p_num_' + file.ID).html(Eci.Resource.ConnectionInterrupted)
            }
          }
        }
      }

      //  接收WebSocket信息
      this.channel.reconnected = function (data) {
        if (that.isUploading) {
          var uploadFiles = that.uploadFiles
          var channel = this

          for (var i = 0, fileLen = uploadFiles.length; i < fileLen; i++) {
            var file = uploadFiles[i]
            if (!file.IsComplete) {
              var eciProgress = 'eci_p_progress_' + file.ID
              document.getElementById(eciProgress).style.backgroundColor = ''

              file.IsStop = false
              file.IsContinue = true

              var closedSector = $('#eci_p_close_' + file.ID)
              closedSector.addClass('icon-icon_No')
              closedSector.removeClass('icon-sup-0039-go-back')
              file.ContinueUpload(channel, 'Handler.UploadFile')
            }
          }
        }
      }

      //  接收WebSocket信息
      this.channel.receive = function (data) {
        var fileLen = that.uploadFiles.length

        if (data.State === 'RESUME') {
          //  续传
          for (var i = 0; i < fileLen; i++) {
            var continueFile = that.uploadFiles[i]
            if (continueFile.FileID == data.parameters.FileID) {
              continueFile.UploadBytes = data.ExistentSize
              continueFile.IsContinue = false
              setTimeout(function () {
                continueFile.Upload(that.channel, 'Handler.UploadFile')
              }, 200)
              break
            }
          }
        } else if (data.State === 'COMPLETE') {
          //  上传完成
          if (option.receive) {
            option.receive(data)
          }

          that.currIndex++

          //  每个文件的路径赋值
          for (var i = 0; i < fileLen; i++) {
            if (that.uploadFiles[i].FileID == data.parameters.FileID) {
              that.uploadFiles[i].Path = data.Path
              that.uploadFiles[i].FullName = data.FullName
              that.uploadFiles[i].Folder = data.Folder
              that.uploadFiles[i].ServerID = data.ServerID
              that.uploadFiles[i].FileSize = data.FileSize
              that.uploadFiles[i].ImageCount = data.ImageCount
              that.uploadFiles[i].PageCount = data.PageCount
              that.uploadFiles[i].FileContent = data.FileContent
              that.uploadFiles[i].IsDoc = data.IsDoc
              that.uploadFiles[i].ErrorMessage = ''
              that.uploadFiles[i].FileFormat = 'other'
              break
            }
          }

          //  这批文件发送到外部事件调用
          if (that.complete && that.currIndex === fileLen) {
            var files = that.uploadFiles.slice(that.lastIndex)
            that.lastIndex = that.currIndex
            that.complete(files)
          }
        } else if (
          data.State === 'EXTRACT' ||
          data.State === 'EXTRACTTOGUID' ||
          data.State === 'EXTRACTFROMPATH' ||
          data.State === 'EXTRACTTOGUIDFROMPATH'
        ) {
          if (data.State === 'EXTRACT' || data.State === 'EXTRACTFROMPATH') {
            that.extract(data.ZipFiles)
          } else if (data.State === 'EXTRACTTOGUID' || data.State === 'EXTRACTTOGUIDFROMPATH') {
            that.extract(data.ZipFiles)
          }

          //for (var i = 0; i < that.uploadFiles.length; i++) {
          //    that.decompressedProcess(that.uploadFiles[i]);
          //}
        }
      }

      this.channel.connect(option.ws)
    },

    /**
     * 分析文件
     */
    analysisFiles: function (path) {
      if (this.channel == null) {
        var that = this
        //  建立WebSocket连接
        this.connectServer(connOpt, function () {
          //  上传文件
          that.sendAnalysisFiles(path)
        })
      } else if (this.channel.state() === 1) {
        this.sendAnalysisFiles(path)
      }
    },

    sendAnalysisFiles: function (path) {
      var path2 = path

      if (jQuery.isArray(path)) {
        path2 = ''
        for (var i = 0; i < path.length; i++) {
          path2 += path[i] + '<*>'
        }
      }

      if (this.IsSingleProgress) {
        for (var i = 0; i < this.uploadFiles.length; i++) {
          this.decompressingProcess(this.uploadFiles.length === 1)
        }
      } else {
        for (var i = 0; i < this.uploadFiles.length; i++) {
          this.decompressingProcess(this.uploadFiles[i])
        }
      }

      this.channel.send({
        State: 'EXTRACT',
        Path: path2,
        parameters: {
          IsContinue: false
        }
      })
    },

    /**
     * 分析文件
     */
    extractFiles: function (path) {
      if (this.channel == null) {
        var that = this
        //  建立WebSocket连接
        this.connectServer(connOpt, function () {
          //  上传文件
          that.sendExtractFiles(path)
        })
      } else if (this.channel.state() === 1) {
        this.sendExtractFiles(path)
      }
    },

    sendExtractFiles: function (path) {
      if (this.IsSingleProgress) {
        for (var i = 0; i < this.uploadFiles.length; i++) {
          this.decompressingProcess(this.uploadFiles.length === 1)
        }
      } else {
        for (var i = 0; i < this.uploadFiles.length; i++) {
          this.decompressingProcess(this.uploadFiles[i])
        }
      }

      this.channel.send({
        State: 'EXTRACTTOGUID',
        Path: path,
        parameters: {
          IsContinue: false
        }
      })
    },

    /**
     * 一批文件都上传完毕事件
     */
    complete: function (files) {},

    /**
     * 一批文件都上传完毕解压缩文件事件
     */
    extract: function (files) {},

    /**
     * 显示上传容器
     */
    show: function (files) {
      $('#' + this.id).show()
      var that = this
      //if (this.channel && this.channel.socket && (this.channel.socket.readyState === 3 || this.channel.socket.readyState === 1)) {

      //} else {
      //    //  建立WebSocket连接
      //    this.connectServer(connOpt);
      //    //  上传文件
      //    this.upload(files);
      //}

      if (this.channel == null) {
        //  在网页里添加上传控件窗体
        this.appendHTML()

        //  建立WebSocket连接
        this.connectServer(connOpt, function () {
          //  上传文件
          that.upload(files)
        })
      } else if (this.channel.state() === 1) {
        this.upload(files)
      } else if (this.channel.state() !== 1) {
        this.hide()

        //  在网页里添加上传控件窗体
        this.appendHTML()

        //  建立WebSocket连接
        this.connectServer(connOpt, function () {
          //  上传文件
          that.upload(files)
        })
      }
    },

    /**
     * 在一个拖动过程中，释放鼠标键时触发此事件
     */
    showUpload: function (files) {
      this.show(files)
    },

    /**
     * 隐藏上传容器，并且清空容器
     */
    hide: function () {
      //return;
      if (this.channel != null) {
        this.channel.close()
        this.channel = null
      }

      this.currIndex = 0
      this.lastIndex = 0
      $('#' + this.id).hide() //  隐藏容器
      $('#mask-' + this.id).hide() //  隐藏容器
      this.clearUploadItems() //  清空容器
      this.close()
    },

    /**
     * 获得上传容器
     */
    getUploadBox: function () {
      return document.getElementById('eci-upload-dialog-container')
    },

    /**
     * 在一个拖动过程中，释放鼠标键时触发此事件
     */
    upload: function (files) {
      //this.onFileOpen([files[0]]);
      if (files.length > 0) {
        this.progressContainerId = Math.floor(Math.random() * 0x10000).toString()
        this.onFileOpen(files)
      }
    },

    /**
     * 上传容器添加文件元素
     */
    addUploadItem: function (info) {
      var progressbarId = info.ID

      if (!this.IsSingleProgress) {
        var eciProgressContainer = 'eci_progressbar_container_' + progressbarId
        var eciProgressText = 'eci_p_text_' + progressbarId
        var eciProgress = 'eci_p_progress_' + progressbarId
        var eciProgressNum = 'eci_p_num_' + progressbarId
        var eciProgressClose = 'eci_p_close_' + progressbarId

        $('#' + this.id).append(
          '<div id="' +
            eciProgressContainer +
            '" class="eci-progressbar-container" ><div class="icon-icon_Download eci-progressbar-icon"></div><div class="eci-progressbar-body"><div class="eci-progressbar-body-top eci-progressbar-ver-mid"><span id="' +
            eciProgressText +
            '"></span></div><div class="eci-progressbar-body-center"><div id="' +
            eciProgress +
            '" class="eci-progressbar-length"></div></div><div class="eci-progressbar-body-bottom eci-progressbar-ver-mid"><span  id="' +
            eciProgressNum +
            '"></span></div></div><div class="eci-progressbar-right"><div id="' +
            eciProgressClose +
            '" class="icon-icon_No eci-progressbar-close"></div></div></div>'
        )
        //  进度条显示上传进度
        if (!this.IsSingleProgress) $('#' + eciProgressText).html(info.FileName)
        document.getElementById(eciProgress).style.width = 0
        $('#' + eciProgressNum).empty()
      }

      var channel = this.channel
      setTimeout(function () {
        info.Upload(channel, 'Handler.UploadFile')
      }, 200)
    },

    addSingleUploadItem: function (fileCount) {
      var progressbarId = this.progressContainerId
      var eciProgressContainer = 'eci_progressbar_container_' + progressbarId
      var eciProgressText = 'eci_p_text_' + progressbarId
      var eciProgress = 'eci_p_progress_' + progressbarId
      var eciProgressNum = 'eci_p_num_' + progressbarId
      var eciProgressClose = 'eci_p_close_' + progressbarId

      $('#' + this.id).append(
        '<div id="' +
          eciProgressContainer +
          '" class="eci-progressbar-container" ><div class="icon-icon_Download eci-progressbar-icon"></div><div class="eci-progressbar-body"><div class="eci-progressbar-body-top eci-progressbar-ver-mid"><span id="' +
          eciProgressText +
          '"></span></div><div class="eci-progressbar-body-center"><div id="' +
          eciProgress +
          '" class="eci-progressbar-length"></div></div><div class="eci-progressbar-body-bottom eci-progressbar-ver-mid"><span  id="' +
          eciProgressNum +
          '"></span></div></div><div class="eci-progressbar-right"><div id="' +
          eciProgressClose +
          '" class="icon-icon_No eci-progressbar-close"></div></div></div>'
      )
      //  进度条显示上传进度
      if (fileCount == 1) {
        $('#' + eciProgressText).html(Eci.Resource.SingletonSingleFile)
      } else {
        $('#' + eciProgressText).html(Eci.Resource.SingletonMultiFiles.replace('$file_count$', fileCount))
      }

      document.getElementById(eciProgress).style.width = 0
      $('#' + eciProgressNum).empty()
    },

    /**
     * 清空上传容器
     */
    clearUploadItem: function (id) {
      var len = this.uploadFiles.length
      var index = $("div[id^='eci_p_close_']").index($('#' + id))
      this.uploadFiles[index].IsStop = true
      var id2 = id.replace('eci_p_close_', '')
      var containerId = 'eci_progressbar_container_' + id2

      for (var i = len - 1; i >= 0; i--) {
        if (this.uploadFiles[i].ID == id2) {
          if (this.uploadFiles[i].IsComplete) {
            //  删除已经上传完成的文件需要减一
            this.currIndex--
          }

          if (this.lastIndex > i) {
            //  删除前几批上传完成的文件需要减一
            this.lastIndex--
          }

          //  删除当前文件
          this.uploadFiles.splice(i, 1)

          break
        }
      }

      $('#' + containerId).animate(
        {
          height: 0
        },
        500,
        '',
        function () {
          $('#' + containerId).remove()
        }
      )

      if (len === 1 || this.IsSingleProgress) {
        this.uploadFiles = []
        this.hide()
      }
    },

    /**
     * 清空上传容器
     */
    stopUpload: function (id) {
      var closedSector = $('#' + id)

      var index = $("div[id^='eci_p_close_']").index(closedSector)
      var file = this.uploadFiles[index]

      if (closedSector.hasClass('icon-icon_No')) {
        file.IsStop = true

        //var id2 = id.replace("eci_p_close_", "");

        closedSector.removeClass('icon-icon_No')
        closedSector.addClass('icon-sup-0039-go-back')
      } else {
        file.IsStop = false
        file.IsContinue = true
        var channel = this.channel
        setTimeout(function () {
          file.ContinueUpload(channel, 'Handler.UploadFile')
        }, 200)

        closedSector.addClass('icon-icon_No')
        closedSector.removeClass('icon-sup-0039-go-back')
      }
    },

    /**
     * 清空上传容器
     */
    clearUploadItems: function () {
      this.uploadFiles = []
      this.reConnectTimes = 0
      this.currIndex = 0
      this.lastIndex = 0
      this.progressContainerId = null

      $('.eci-progressbar-container').remove()
      $('#eci-upload-dialog').remove()
      $('#mask-eci-upload-dialog').remove()
      $('.eci-progressbar').remove()
    },

    /**
     * 打开拖入上传容器的文件
     */
    onFileOpen: function (files) {
      var that = this

      if (files.length > 0) {
        var guid = ''

        if (files.length > 1) {
          guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (Math.random() * 16) | 0,
              v = c == 'x' ? r : (r & 0x3) | 0x8
            return v.toString(16)
          })
        }

        if (files.length > 0 && this.IsSingleProgress) {
          this.addSingleUploadItem(files.length)
        }

        for (var i = 0; i < files.length; i++) {
          var info = new Eci.IO.File(files[i])

          if (this.IsSingleProgress) {
            info.ContainerId = this.progressContainerId
          }

          if (this.IsRealName) {
            info.UploadGuid = guid
            info.IsRealName = true
          }

          this.uploadFiles.push(info)
          info.UploadProcess = function (file) {
            that.onUploadProcess(file)
          }
          this.addUploadItem(info)
        }
      }

      $("div[id^='eci_p_close_']").click(function () {
        if (this.IsSingleProgress) {
          that.clearUploadItem(that.progressContainerId)
        } else {
          that.clearUploadItem(this.id)
        }
        $(this).unbind('click')
      })
    },

    /**
     * 进度条显示上传进度
     */
    onUploadProcess: function (file) {
      var progressbarId = file.ID

      if (file.ContainerId) {
        progressbarId = file.ContainerId
      }

      var eciProgress = 'eci_p_progress_' + progressbarId
      var eciProgressNum = 'eci_p_num_' + progressbarId

      var width
      var html

      if (this.IsSingleProgress) {
        var bytes = 0,
          fileSize = 0,
          pageIndex = 0,
          pages = 0
        for (var i = 0; i < this.uploadFiles.length; i++) {
          bytes += this.uploadFiles[i].UploadBytes
          fileSize += this.uploadFiles[i].FileSize
          pageIndex += this.uploadFiles[i].PageIndex
          pages += this.uploadFiles[i].Pages
        }

        html = Math.round((bytes / 1024) * 100) / 100 + 'KB / ' + Math.round((fileSize / 1024) * 100) / 100 + 'KB'
        width = (pageIndex / pages) * $('.eci-progressbar-body-center').width()
      } else {
        html =
          Math.round((file.UploadBytes / 1024) * 100) / 100 +
          'KB / ' +
          Math.round((file.FileSize / 1024) * 100) / 100 +
          'KB'
        width = (file.PageIndex / file.Pages) * $('.eci-progressbar-body-center').width()
      }

      if (document.getElementById(eciProgress)) {
        document.getElementById(eciProgress).style.width = width + 'px'
        $('#' + eciProgressNum).html(html)
      }
    },

    /**
     * Singleton模式时, file 类型为 bool
     * 非Singleton模式时, file 类型为 Eci.IO.File
     * @param {} file
     * @returns {}
     */
    decompressingProcess: function (file) {
      var eciProgressNum
      var eciProgressText

      if (this.IsSingleProgress) {
        eciProgressNum = 'eci_p_num_' + this.progressContainerId
        eciProgressText = 'eci_p_text_' + this.progressContainerId

        if (file) {
          $('#' + eciProgressNum).html(Eci.Resource.SingletonSingleFileStatus)
          $('#' + eciProgressText).html(Eci.Resource.SingletonSingleFileComplete)
        } else {
          $('#' + eciProgressNum).html(Eci.Resource.SingletonSingleFileStatus)
          $('#' + eciProgressText).html(Eci.Resource.SingletonMultiFilesComplete)
        }
      } else {
        var progressbarId = file.ID
        eciProgressNum = 'eci_p_num_' + progressbarId
        $('#' + eciProgressNum).html(Eci.Resource.Decompressing)
      }
    },

    decompressedProcess: function (file) {
      var eciProgressNum

      if (this.IsSingleProgress) {
        eciProgressNum = 'eci_p_num_' + this.progressContainerId
      } else {
        var progressbarId = file.ID
        eciProgressNum = 'eci_p_num_' + progressbarId
      }

      $('#' + eciProgressNum).html(Eci.Resource.Decompressed)
    }
  }

  obj.init(connOpt, options)
  return obj
}

Eci.Resource = {
  Decompressed: 'Source files processing has been completed.',
  Decompressing: 'Source files are being processed.',
  ConnectionInterrupted: 'Connection interrupted.',
  NotConnected: 'Failed to connect to the server. Please try again later or contact administrator.',
  SingletonSingleFile: '1 source file is being uploaded ...',
  SingletonMultiFiles: '$file_count$ source files are being uploaded ...',
  SingletonSingleFileStatus: 'Checking the content of source file ...',
  SingletonMultiFilesStatus: 'Checking the content of source files ...',
  SingletonSingleFileComplete: '1 source file is have been uploaded successfully.',
  SingletonMultiFilesComplete: '$file_count$ source files are have been uploaded successfully.'
}
